<?php
/**
 * Created by PhpStorm
 * User: whh
 * Date: 2022/12/3
 * Time: 14:32
 */

namespace app\backstage\logic;


use app\common\model\Novel;
use app\common\model\NovelChapter;
use app\common\model\NovelClass;
use app\common\model\NovelClassSon;
use app\common\model\NovelFreq;
use app\common\model\NovelLabel;
use app\common\model\NovelMpParty;
use think\Db;

class NovelLogic
{

    /**
     * @param $where
     * @param string $order
     * @param string $field
     * @return Novel[]|\think\Collection
     * @Author: whh
     */
    public function novelList($where, $order = '', $field = '*')
    {
        $novel = new Novel();
        return $novel->field($field)->where($where)->order($order)->select();
    }

    /**
     * @param $params
     * @param int $id
     * @throws \think\Exception
     */
    public function setNovel($params, $id = 0)
    {
        $params['lead'] = str_replace("，", ",", $params['lead']);
        if ($id) {
            $model = Novel::get($id);
            $field = ['title','origin_title', 'author', 'lead', 'cover', 'in_shelf', 'update_status', 'scale', 'freq_id', 'class_id', 'brief', 'recom_chapter', 'words_fee', 'son_class_id'];
            $model->labels()->detach();
            if (isset($params['label']) && $params['label']) {
                $model->labels()->attach(array_values($params['label']));
            }
            $model->allowField($field)->save($params);
        } else {
            $params['origin_title'] = $params['title'];
            $field = ['origin_title', 'lead', 'title', 'author', 'cover', 'in_shelf', 'update_status', 'scale', 'freq_id', 'class_id', 'brief', 'words_fee', 'son_class_id'];
            $model = new Novel();
            $model->allowField($field)->save($params);
            if (isset($params['label']) && $params['label']) {
                $model->labels()->attach(array_values($params['label']));
            }
            NovelMpParty::insert([
                'novel_id' => $model->id,
                'party_code' => 'upload',
                'party_novel_id' => $model->id,
            ]);
        }
    }


    /**
     * 设置章节
     * @param $params
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function setChapter($params)
    {
        $novel = Novel::get($params['novel_id']);
        if (isset($params['chapter_no']) && $params['chapter_no']) {
            $where[] = ['novel_id', '=', $params['novel_id']];
            $where[] = ['chapter_no', '=', $params['chapter_no']];
            $model = NovelChapter::where($where)->findOrFail();
            $field = ['name', 'is_pay', 'words'];
            $params['words'] = clearHtmlGetNum($params['content']);
            $model->allowField($field)->save($params);
            $model->setContent($params['content']);
        } else {
            $field = ['novel_id', 'chapter_no', 'name', 'is_pay', 'words'];
            $model = new NovelChapter();
            $maxNo = NovelChapter::where("novel_id", $novel->id)->max('chapter_no');
            $save = [
                'novel_id' => $novel->id,
                'chapter_no' => $maxNo + 1,
                'name' => $params['name'],
                'is_pay' => $params['is_pay'],
                'words' => clearHtmlGetNum($params['content']),
            ];
            $model->allowField($field)->save($save);
            $model->setContent($params['content']);
            $novel->chapter_up_time = date("Y-m-d H:i:s");
        }
        $novel->number_words = NovelChapter::where("novel_id", $novel->id)->sum('words');
        $novel->save();
    }


    /**
     * 设置专属书籍
     * @param $nid
     * @param $agentIds
     * @param int $isAdd
     * @return \think\response\Json
     * @throws \think\Exception
     * @Author: whh
     */
    public function setExclusive($nid, $agentIds, $isAdd = 0)
    {
        $novel = Novel::get($nid);
        if (!$novel) {
            return errJson('书籍不存在');
        }
        if ($isAdd == 1) {
            if ($novel->is_exclusive == 1) {
                return errJson('专属书籍已存在，请到表格内操作');
            }
        } else {
            $novel->agents()->detach();
        }
        $novel->is_exclusive = 1;
        if ($agentIds) {
            $agentIds = explode(',', $agentIds);
            $novel->agents()->attach($agentIds);
        }
        $novel->save();
        return sucJson();
    }


    /**
     * 设置标签
     * @param $name
     * @param null $id
     * @return \think\response\Json
     */
    public function setLabel($name, $id = null)
    {
        if ($id) {
            $label = NovelLabel::get($id);
            if (!$label) {
                return sucJson('标签不存在');
            }
        } else {
            $label = new NovelLabel();
        }
        $label->name = $name;
        $label->save();
        return sucJson();
    }

    /**
     * 频道列表
     * @param $where
     * @param $page
     * @param $limit
     * @return \think\response\Json
     * @Author: whh
     */
    public function freqList($where, $page, $limit)
    {
        $list = NovelFreq::getList($where, '*', 'id desc', $page, $limit);
        foreach ($list as $k => $v) {
            $list[$k]['class_count'] = count($v->sonClass);
            $list[$k]['novel_count'] = Novel::where("freq_id", $v->id)->count();
        }
        $count = NovelFreq::getCount($where);
        return sucJson($list, $count);
    }


    /**
     * 删除分类
     * @param $id
     * @return \think\response\Json
     * @throws \Exception
     */
    public function delFreq($id)
    {
        $freq = NovelFreq::get($id);
        if (!$freq) {
            return errJson('频道不存在');
        }
        if (count($freq->subSonClass)) {
            return errJson('删除失败，存在下属分类或子分类');
        }
        if (count($freq->sonClass)) {
            return errJson('删除失败，存在下属分类');
        }
        $novelCount = Novel::where("freq_id", $id)->count();
        if ($novelCount) {
            return errJson('删除失败，存在下属书籍');
        }
        $freq->delete();
        return sucJson();
    }

    /**
     * 分类接口
     * @param $where
     * @param $page
     * @param $limit
     * @param $orderBy
     * @return \think\response\Json
     */
    public function classList($where, $page, $limit, $orderBy)
    {
        $list = NovelClass::getList($where, '*', $orderBy, $page, $limit, ['freq']);
        foreach ($list as $k => $v) {
            $list[$k]['novel_count'] = Novel::where("class_id", $v->id)->count();
        }
        $count = NovelClass::getCount($where);
        return sucJson($list, $count);
    }

    /**
     * 设置频道
     * @param $name
     * @param int $id
     * @return \think\response\Json
     * @Author: whh
     */
    public function setFreq($name, $id = 0)
    {
        $nameFreq = NovelFreq::getByName($name);
        if (!$id) {
            if ($nameFreq) {
                return errJson('此频道已存在');
            }
            $freq = new NovelFreq();
        } else {
            if ($nameFreq && $nameFreq->id != $id) {
                return errJson('此频道已存在');
            }
            $freq = NovelFreq::get($id);
            if (!$freq) {
                return errJson('编辑失败，频道不存在');
            }
        }
        $freq->name = $name;
        $freq->save();
        return sucJson();
    }


    /**
     * 设置分类
     * @param $params
     * @return \think\response\Json
     */
    public function setClass($params)
    {
        $freqIds = $params['freqIds'];
        if (!$freqIds) {
            return errJson('频道必选');
        }
        $freqAllId = NovelFreq::column('id');
        $diff = array_diff($freqIds, $freqAllId);
        if ($diff) {
            return errJson('参数异常，频道非法');
        }
        $nameClass = NovelClass::getByName($params['name']);

        if (isset($params['id']) && $params['id']) {
            $class = NovelClass::get($params['id']);
            if (!$class) {
                return errJson('编辑失败，分类不存在');
            }
            if ($nameClass && $nameClass->id != $params['id']) {
                return errJson('此分类已存在');
            }
            $freqArr = $class->freq->toArray();
            $haveFreqIdArr = array_column($freqArr, 'id');
            $diff = array_diff($haveFreqIdArr, $freqIds);//被删除的频道
            foreach ($diff as $freqId) {
                $where = [];
                $where[] = ['class_id', '=', $params['id']];
                $where[] = ['freq_id', '=', $freqId];
                $count = NovelClassSon::where($where)->count();
                if ($count > 0) {
                    $freq = NovelFreq::get($freqId);
                    return errJson("修改失败，在{$freq->name} · {$class->name}下有子分类");
                }
                $count = Novel::where($where)->count();
                if ($count > 0) {
                    $freq = NovelFreq::get($freqId);
                    return errJson("修改失败，在{$freq->name} · {$class->name}下有书籍");
                }
            }
            //删除多余频道
            if ($diff) {
                $class->freq()->detach($diff);
            }
            $noHave = array_diff($freqIds, $haveFreqIdArr);//中间表没有的
            $class->freq()->saveAll($noHave);//添加新频道
            $class->name = $params['name'];
            $class->en_name = $params['en_name'];
            $class->save();
        } else {
            if ($nameClass) {
                return errJson('此分类已存在');
            }
            $class = new NovelClass();
            $class->name = $params['name'];
            $class->en_name = $params['en_name'];
            $class->save();
            $class->freq()->saveAll($freqIds);
        }
        return sucJson();
    }

    /**
     * 删除分类
     * @param $id
     * @return \think\response\Json
     * @throws \Exception
     */
    public function delClass($id)
    {
        $class = NovelClass::get($id);
        if (!$class) {
            return errJson('分类不存在');
        }
        if (count($class->subSonClass)) {
            return errJson('删除失败，存在子分类');
        }
        $novelCount = Novel::where("class_id", $id)->count();
        if ($novelCount) {
            return errJson('删除失败，存在下属书籍');
        }
        $class->delete();
        return sucJson();
    }


    /**
     * 子分类列表
     * @param $where
     * @param $page
     * @param $limit
     * @return \think\response\Json
     */
    public function classSonList($where, $page, $limit)
    {
        $list = NovelClassSon::getList($where, '*', 'id desc', $page, $limit, ['freq', 'parent_class']);
        foreach ($list as $k => $v) {
            $list[$k]['novel_count'] = Novel::where("son_class_id", $v->id)->count();
        }
        $count = NovelClassSon::getCount($where);
        return sucJson($list, $count);
    }


    public function setClassSon($data)
    {
        $freq = NovelFreq::get($data['freq_id']);
        $sonClass = $freq->sonClass->toArray();
        $freqClassIds = array_column($sonClass, 'id');
        if (!in_array($data['class_id'], $freqClassIds)) {
            return errJson('参数异常，父级分类不在此频道下');
        }
        $nameSon = NovelClassSon::getByName($data['name']);
        if (isset($data['id']) && $data['id']) {
            $son = NovelClassSon::get($data['id']);
            if (!$son) {
                return errJson('编辑失败，子分类不存在');
            }
            if ($nameSon && $data['id'] != $nameSon->id) {
                return errJson('此子分类名称已存在');
            }
            if ($son->freq_id != $data['freq_id'] || $son->class_id != $data['class_id']) {
                $count = Novel::where("son_class_id", $son->id)->count();
                if ($count) {
                    return errJson('修改失败，此子分类和上级频道和上级分类下已有对应书籍');
                }
            }
            $son->freq_id = $data['freq_id'];
            $son->class_id = $data['class_id'];
            $son->name = $data['name'];
            $son->en_name = $data['en_name'];
            $son->save();
        } else {
            if ($nameSon) {
                return errJson('此子分类名称已存在');
            }
            $sonModel = new NovelClassSon();
            $sonModel->name = $data['name'];
            $sonModel->en_name = $data['en_name'];
            $sonModel->class_id = $data['class_id'];
            $sonModel->freq_id = $data['freq_id'];
            $sonModel->save();
        }
        return sucJson();
    }


    /**
     * 删除子分类
     * @param $id
     * @return \think\response\Json
     * @throws \Exception
     * @Author: whh
     */
    public function delClassSon($id)
    {
        $son = NovelClassSon::get($id);
        if (!$son) {
            return errJson('此子分类不存在');
        }
        Novel::where("son_class_id", $id)->setField('son_class_id', 0);
        $son->delete();
        return sucJson();
    }


    /**
     * 书籍分析
     * @param $where
     * @param $page
     * @param $limit
     * @param $orderBy
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @Author: whh
     */
    public function dataAnalysisList($where, $page, $limit, $orderBy)
    {
        if(request()->_role->alias == 'content' || request()->_role->alias == 'operator')
        {
            $table = 'rp_novel_date_daily_discount';
        }else{
            $table = 'rp_novel_date_daily';
        }

        $field = "nid,sum(uv) uv,sum(money) money,sum(cuv) cuv,sum(pay_uv) pay_uv,sum(use_coin) use_coin,sum(new_uv) new_uv,sum(new_pay_uv) new_pay_uv,sum(new_money) new_money";
        $list = Db::table($table)
            ->field($field)
            ->where($where)
            ->page($page, $limit)
            ->group('nid')
            ->order($orderBy)
            ->select();
        $nidArr = array_column($list, 'nid');
        $novels = Db::table("novel")->where('id', 'in', $nidArr)->column('title', 'id');
        foreach ($list as $k => $v) {
            $list[$k]['name'] = isset($novels[$v['nid']]) ? $novels[$v['nid']] : '';
            $list[$k]['pay_rate'] = getQuotient($v['pay_uv'], $v['uv'],2,'m',100) . "%";
            $list[$k]['c_rate'] = getQuotient($v['cuv'], $v['uv'],2,'m',100) . "%";
            $list[$k]['c_rj'] = getQuotient($v['use_coin'], $v['cuv']);
            $list[$k]['new_rate'] = getQuotient($v['new_pay_uv'], $v['new_uv'],2,'m',100) . "%";
            $list[$k]['money'] = getQuotient($v['money'], 100);
            $list[$k]['new_money'] = getQuotient($v['new_money'], 100);
        }
        $count = Db::table($table)
            ->where($where)
            ->group('nid')
            ->count();
        return sucJson($list, $count);
    }


    /**
     * 书籍分析每日明细
     * @param $nid
     * @param $where
     * @param $page
     * @param $limit
     * @param $orderBy
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @Author: whh
     */
    public function dataDetail($nid, $where, $page, $limit, $orderBy)
    {
        if(request()->_role->alias == 'content')
        {
            $table = 'rp_novel_date_daily_discount';
        }else{
            $table = 'rp_novel_date_daily';
        }

        $field = "nid,read_date,sum(uv) uv,sum(money) money,sum(cuv) cuv,sum(pay_uv) pay_uv,sum(use_coin) use_coin,sum(new_uv) new_uv,sum(new_pay_uv) new_pay_uv,sum(new_money) new_money";
        $list = Db::table($table)
            ->where($where)
            ->where('nid', $nid)
            ->field($field)
            ->page($page, $limit)
            ->order($orderBy)
            ->group('read_date')
            ->select();
        $name = Db::table("novel")->where('id', '=', $nid)->value('title');
        foreach ($list as $k => $v) {
            $list[$k]['name'] = $name;
            $list[$k]['pay_rate'] = getQuotient($v['pay_uv'], $v['uv'],2,'m',100) . "%";
            $list[$k]['c_rate'] = getQuotient($v['cuv'], $v['uv'],2,'m',100) . "%";
            $list[$k]['c_rj'] = getQuotient($v['cuv'], $v['use_coin']);
            $list[$k]['new_rate'] = getQuotient($v['new_pay_uv'], $v['new_uv'],2,'m',100) . "%";
            $list[$k]['money'] = getQuotient($v['money'], 100);
            $list[$k]['new_money'] = getQuotient($v['new_money'], 100);
        }
        $count = Db::table($table)
            ->where($where)
            ->where('nid', $nid)
            ->group('read_date')
            ->count();
        return sucJson($list, $count);
    }

    /**
     * 复充统计
     * @param $nid
     * @param $where
     * @return array
     * @Author: whh
     */
    public function againFxList($nid, $where)
    {
        $where[] = ['nid', '=', $nid];
        $max = Db::table("rp_novel_recharge_repeat_detail")->where($where)->max('pay_count');
        $list = [];
        for ($i = 1; $i <= $max; $i++) {
            $list[$i]['index'] = $i;
            $list[$i]['count'] = Db::table("rp_novel_recharge_repeat_detail")->where($where)->where("pay_count", '>=', $i)->group('uid')->count('id') ?? 0;
            $list[$i]['fc_rate'] = getQuotient($list[$i]['count'], $list[1]['count'],2,'m',100) . "%";
        }
        return $list;
    }

}